﻿using AutoMapper;
using JWT;
using Newtonsoft.Json;
using SGSBillBoard.Context;
using SGSBillBoard.DTO.Model;
using SGSBillBoard.Model;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.Data.Entity;
using System.Data.Entity.Core.Objects;
using System.Data.SqlClient;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using System.Web.Http.Cors;

namespace SGSBillBoard.WebAPI.Controllers
{
    public class ValuesController : ApiController
    {

        private SGSContext context;
        private int CurrrentSeason
        {
            get { return int.Parse(ConfigurationManager.AppSettings["season"]); }
        }
        [Route("api/scores")]
        // GET api/values
        public IEnumerable<ScoreDto> Get()
        {
            try
            {
                context = new SGSContext();
                List<Score> list = context.Scores.ToList();
                List<ScoreDto> scoreDtos = Mapper.Map<List<Score>, List<ScoreDto>>(list);

                return scoreDtos.OrderByDescending(o => o.Session.GameDate).Take(5);

            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        [Route("api/scores/winner")]
        public IEnumerable<ScoreDto> GetWinners()
        {
            context = new SGSContext();
            List<Score> list = context.Scores.Where(o => o.IsWinner).ToList();
            List<ScoreDto> scoreDtos = Mapper.Map<List<Score>, List<ScoreDto>>(list);
            return scoreDtos.OrderByDescending(o => o.Session.GameDate).Take(10);
        }

        private int GetWinnerNationBySessionID(Guid id)
        {
            context = new SGSContext();
            var nation = context.Scores.Where(o => o.Session.ID == id && o.IsWinner).FirstOrDefault().Chief.Nation;
            return (int)nation;

        }
        [Route("api/scores/lasttensessions")]
        [HttpGet]
        public IEnumerable<SessionDetailDto> GetLastTenSessions()
        {
            context = new SGSContext();
            var sessions = context.Sessions.OrderByDescending(x => x.GameDate).Take(10).ToList();
            var sessionIds = sessions.Select(x => x.ID).ToList();
            var scores = context.Scores.Where(x => sessionIds.Contains(x.Session.ID)).ToList();


            var result = sessions.Select(x => new SessionDetailDto()
            {
                ID = x.ID,
                Season = int.Parse(ConfigurationManager.AppSettings["season"]),
                PlayerNumber = x.PlayerNumber,
                GameDate = x.GameDate,
                WinnerNation = GetWinnerNationBySessionID(x.ID),
                ScoreDetails = scores.Where(y => y.Session.ID == x.ID).Select(y => new ScoreDetailDto()
                {
                    IsShownFirst = y.IsShowFirst,
                    IsWinner = y.IsWinner,
                    Kills = y.Kills,
                    Player = new PlayerDto()
                    {
                        Department = y.Player.Department,
                        ID = y.Player.ID,
                        Name = y.Player.Name
                    },
                    Chief = new FighterDto()
                    {
                        ID = y.Chief.ID,
                        Name = y.Chief.Name,
                        Nation = (DTO.Model.Nations)((int)y.Chief.Nation)
                    },
                    Vice = new FighterDto()
                    {
                        ID = y.Vice.ID,
                        Name = y.Vice.Name,
                        Nation = (DTO.Model.Nations)((int)y.Vice.Nation)
                    },
                }).ToList()
            });

            return result;
        }

        [Route("api/scores/{id}")]
        public IEnumerable<ScoreDto> GetScoresByScoreID(Guid id)
        {
            context = new SGSContext();
            var score = context.Scores.SingleOrDefault(o => o.ID == id);
            var scores = context.Scores.Where(o => o.Session.ID == score.Session.ID).ToList();
            List<ScoreDto> scoreDtos = Mapper.Map<List<Score>, List<ScoreDto>>(scores);
            return scoreDtos;
        }

        [Route("api/sessions/{id}")]
        public IEnumerable<ScoreDto> GetScoresBySessionID(Guid id)
        {
            context = new SGSContext();
            var scores = context.Scores.Where(o => o.Session.ID == id).ToList();
            List<ScoreDto> scoreDtos = Mapper.Map<List<Score>, List<ScoreDto>>(scores);
            return scoreDtos;
        }

        [Route("api/showfirst")]
        public IEnumerable<ShowFirstRecord> GetShowFirstRecord()
        {
            context = new SGSContext();
            var list = context.Scores.Where(o => o.IsShowFirst).GroupBy(o => o.Player.Name).ToList();
            List<ShowFirstRecord> result = new List<ShowFirstRecord>();
            int totalgames = context.Sessions.Count();

            foreach (var item in list)
            {
                int participateTotalGames = GetParticipateTotalGamest(item.Key, context);
                int nation = GetHighShowFirstRatioByPlayer(item.Key);
                int wintimes = GetShowFirstThenWinTimes(item.Key);

                result.Add(new ShowFirstRecord { Name = item.Key, Times = item.Count(), MaxShowFirstNation = nation, ShowFirstWinTimes = wintimes, TotalGames = totalgames, ParticipateTotalGames = participateTotalGames });
            }
            return result.OrderByDescending(o => o.Times).ThenByDescending(o => o.ShowFirstWinTimes);
        }

        private int GetParticipateTotalGamest(string name, SGSContext context)
        {
            return context.Scores.Where(o => o.Player.Name == name).Count();
        }

        [Route("api/showfirst/{name}")]
        public object[] GetShowFirstByName(string name)
        {
            int season = int.Parse(ConfigurationManager.AppSettings["season"]);
            List<ArrayList> lists = new List<ArrayList>();

            ArrayList list = new ArrayList();
            context = new SGSContext();
            list.Add(context.Scores.Where(o => o.Player.Name == name && o.IsShowFirst && o.Chief.Nation == Model.Nations.魏).Count());
            list.Add(context.Scores.Where(o => o.Player.Name == name && o.IsShowFirst && o.Chief.Nation == Model.Nations.蜀).Count());
            list.Add(context.Scores.Where(o => o.Player.Name == name && o.IsShowFirst && o.Chief.Nation == Model.Nations.吴).Count());
            list.Add(context.Scores.Where(o => o.Player.Name == name && o.IsShowFirst && o.Chief.Nation == Model.Nations.群).Count());
            lists.Add(list);

            ArrayList listAll = new ArrayList();
            listAll.Add(context.Scores.Where(o => o.Player.Name == name && o.IsShowFirst && o.Chief.Nation == Model.Nations.魏 && o.Session.Season == season).Count());
            listAll.Add(context.Scores.Where(o => o.Player.Name == name && o.IsShowFirst && o.Chief.Nation == Model.Nations.蜀 && o.Session.Season == season).Count());
            listAll.Add(context.Scores.Where(o => o.Player.Name == name && o.IsShowFirst && o.Chief.Nation == Model.Nations.吴 && o.Session.Season == season).Count());
            listAll.Add(context.Scores.Where(o => o.Player.Name == name && o.IsShowFirst && o.Chief.Nation == Model.Nations.群 && o.Session.Season == season).Count());
            lists.Add(listAll);

            return lists.ToArray();
        }

        [Route("api/winners/{name}/{season}")]
        public object[] GetWinnerNationsByName(string name, int season)
        {
            ArrayList list = new ArrayList();
            context = new SGSContext();
            if (season == 0)
            {
                list.Add(context.Scores.Where(o => o.Player.Name == name && o.IsWinner && o.Chief.Nation == Model.Nations.魏).Count());
                list.Add(context.Scores.Where(o => o.Player.Name == name && o.IsWinner && o.Chief.Nation == Model.Nations.蜀).Count());
                list.Add(context.Scores.Where(o => o.Player.Name == name && o.IsWinner && o.Chief.Nation == Model.Nations.吴).Count());
                list.Add(context.Scores.Where(o => o.Player.Name == name && o.IsWinner && o.Chief.Nation == Model.Nations.群).Count());
            }
            else
            {
                list.Add(context.Scores.Where(o => o.Player.Name == name && o.IsWinner && o.Chief.Nation == Model.Nations.魏 && o.Session.Season == season).Count());
                list.Add(context.Scores.Where(o => o.Player.Name == name && o.IsWinner && o.Chief.Nation == Model.Nations.蜀 && o.Session.Season == season).Count());
                list.Add(context.Scores.Where(o => o.Player.Name == name && o.IsWinner && o.Chief.Nation == Model.Nations.吴 && o.Session.Season == season).Count());
                list.Add(context.Scores.Where(o => o.Player.Name == name && o.IsWinner && o.Chief.Nation == Model.Nations.群 && o.Session.Season == season).Count());
            }
            return list.ToArray();
        }

        [Route("api/allgames/{name}/{season}")]
        public object[] GetAllGamesByName(string name, int season)
        {
            ArrayList list = new ArrayList();
            context = new SGSContext();
            if (season == 0)
            {
                list.Add(context.Scores.Where(o => o.Player.Name == name && o.Chief.Nation == Model.Nations.魏).Count());
                list.Add(context.Scores.Where(o => o.Player.Name == name && o.Chief.Nation == Model.Nations.蜀).Count());
                list.Add(context.Scores.Where(o => o.Player.Name == name && o.Chief.Nation == Model.Nations.吴).Count());
                list.Add(context.Scores.Where(o => o.Player.Name == name && o.Chief.Nation == Model.Nations.群).Count());
            }
            else
            {
                list.Add(context.Scores.Where(o => o.Player.Name == name && o.Chief.Nation == Model.Nations.魏 && o.Session.Season == season).Count());
                list.Add(context.Scores.Where(o => o.Player.Name == name && o.Chief.Nation == Model.Nations.蜀 && o.Session.Season == season).Count());
                list.Add(context.Scores.Where(o => o.Player.Name == name && o.Chief.Nation == Model.Nations.吴 && o.Session.Season == season).Count());
                list.Add(context.Scores.Where(o => o.Player.Name == name && o.Chief.Nation == Model.Nations.群 && o.Session.Season == season).Count());
            }
            return list.ToArray();
        }



        [Route("api/history")]
        public IEnumerable<HistoryScoreRecord> GetHistoryRecords()
        {
            context = new SGSContext();
            var users = context.Players.ToList();
            List<HistoryScoreRecord> list = new List<HistoryScoreRecord>();

            foreach (var user in users)
            {
                var record = new HistoryScoreRecord();
                record.Name = user.Name;
                record.TotalGames = context.Scores.Where(o => o.Player.Name == user.Name).Count();
                record.WinnerGames = context.Scores.Where(o => o.Player.Name == user.Name && o.IsWinner).Count();
                record.CareeristGames = context.Scores.Where(o => o.Player.Name == user.Name && o.IsCareerist).Count();
                record.CareeristWinnerGames = context.Scores.Where(o => o.Player.Name == user.Name && o.IsCareerist && o.IsWinner).Count();
                var solos = context.Scores.Where(o => o.Player.Name == user.Name && o.IsWinner).ToList();
                int count = 0;
                record.RepresentNation = GetHighWinnerNationRatioByPlayer(user.Name);
                foreach (var solo in solos)
                {
                    if (context.Scores.Where(o => o.Session.ID == solo.Session.ID).Count(p => p.IsWinner) > 1)
                    {
                        count = count + 1;
                    }
                }
                record.TotalKills = context.Scores.Where(o => o.Player.Name == user.Name).Sum(o => o.Kills);
                record.SoloWinnerGames = solos.Count() - count;
                record.CooperationWinnerGames = solos.Count() - record.SoloWinnerGames;
                list.Add(record);
            }
            return list.Where(o => o.TotalGames > 24).OrderByDescending(o => o.Ratio);
        }

        [Route("api/players")]
        public IEnumerable<PlayerDto> GetAllPlayers()
        {
            context = new SGSContext();
            var list = context.Scores.Where(o => o.IsShowFirst).Select(p => p.Player).Distinct().ToList();

            List<PlayerDto> playerDtos = Mapper.Map<List<Player>, List<PlayerDto>>(list);
            return playerDtos;
        }
        private int GetHighShowFirstRatioByPlayer(string name)
        {
            context = new SGSContext();
            var dic = new Dictionary<int, int>();
            dic.Add(0, context.Scores.Where(o => o.IsShowFirst && o.Player.Name == name && o.Chief.Nation == Model.Nations.魏).Count());
            dic.Add(1, context.Scores.Where(o => o.IsShowFirst && o.Player.Name == name && o.Chief.Nation == Model.Nations.蜀).Count());
            dic.Add(2, context.Scores.Where(o => o.IsShowFirst && o.Player.Name == name && o.Chief.Nation == Model.Nations.吴).Count());
            dic.Add(3, context.Scores.Where(o => o.IsShowFirst && o.Player.Name == name && o.Chief.Nation == Model.Nations.群).Count());
            var nation = dic.Values.Max();
            return dic.FirstOrDefault(o => o.Value == nation).Key;
        }

        private int GetShowFirstThenWinTimes(string name)
        {
            context = new SGSContext();

            int times = context.Scores.Where(o => o.IsWinner && o.IsShowFirst && o.Player.Name == name).Count();
            return times;

        }

        private int GetScoresForCareerist(string name, out int loseGameCount)
        {
            var list = context.Scores.Where(o => o.IsCareerist && o.Player.Name == name && o.IsWinner && o.Session.Season == CurrrentSeason).ToList();
            loseGameCount = context.Scores.Where(o => !o.IsWinner && o.Player.Name == name && o.Session.Season == CurrrentSeason).Count();
            int result = 0;
            foreach (var item in list)
            {
                int count = item.Session.PlayerNumber;
                result = result + count;
            }
            return result;
        }

        private int GetKillsByPlayer(string name)
        {

            context = new SGSContext();
            var count = context.Scores.Where(o => o.Player.Name == name && o.Session.Season == CurrrentSeason).Sum(o => o.Kills);
            return count;
        }

        private List<Combination> GetCombinations()
        {
            context = new SGSContext();
            var list = context.Database.SqlQuery<Combination>("GetPowerTwins").ToList();
            return list;
        }

        [Route("api/top20/{page}")]
        public IEnumerable<Combination> GetTop20Combinations(int page)
        {
            var list = GetCombinations();
            var list2 = list;
            context = new SGSContext();
            var result = new List<Combination>();
            var simpleList = new List<SimpleCombination>();

            foreach (var outItem in list)
            {
                foreach (var inItem in list2)
                {
                    if (outItem.Chief_ID == inItem.Vice_ID && outItem.Vice_ID == inItem.Chief_ID)
                    {
                        int sum = outItem.Num + inItem.Num;
                        if (simpleList.Count(o => o.Chief_ID == inItem.Chief_ID && o.Vice_ID == inItem.Vice_ID) == 0)
                        {
                            simpleList.Add(new SimpleCombination { Chief_ID = inItem.Chief_ID, Vice_ID = inItem.Vice_ID, Num = sum, Nation = inItem.Nation });
                        }
                    }
                }
            }

            if (simpleList.Count != 0)
            {
                foreach (var item in simpleList)
                {
                    int win = context.Scores.Count(o => o.IsWinner && ((o.Chief.ID == item.Chief_ID && o.Vice.ID == item.Vice_ID) || (o.Chief.ID == item.Vice_ID && o.Vice.ID == item.Chief_ID)));

                    int total = context.Scores.Count(o => ((o.Chief.ID == item.Chief_ID && o.Vice.ID == item.Vice_ID) || (o.Chief.ID == item.Vice_ID && o.Vice.ID == item.Chief_ID)));

                    var fighter1 = context.Fighters.SingleOrDefault(o => o.ID == item.Chief_ID).Name;
                    var fighter2 = context.Fighters.SingleOrDefault(o => o.ID == item.Vice_ID).Name;

                    if (result.Count(o => o.Fighter1 == fighter1 && o.Fighter2 == fighter2) == 0 && result.Count(o => o.Fighter2 == fighter1 && o.Fighter1 == fighter2) == 0)
                    {
                        result.Add(new Combination { Chief_ID = item.Chief_ID, Vice_ID = item.Vice_ID, Fighter1 = fighter1, Fighter2 = fighter2, Num = item.Num, WinGame = win, TotalGame = total, Nation = item.Nation });
                    }

                }
            }

            return result.OrderByDescending(o => o.TotalGame).ThenByDescending(o => o.Percentage).Skip(page * 10).Take(10);

        }

        [Route("api/winratio")]
        public IEnumerable<WinRatio> GetWinRatio()
        {
            context = new SGSContext();

            //var list1 = context.Scores.Where(o => o.IsWinner && o.Session.Season == CurrrentSeason);

            var list = context.Scores.Where(o => o.IsWinner && !o.IsCareerist && o.Session.Season == CurrrentSeason).GroupBy(o => o.Player.Name).ToList();
            List<WinRatio> result = new List<WinRatio>();
            int loseGameCount = 0;
            foreach (var item in list)
            {
                int kill = GetKillsByPlayer(item.Key);
                int highWinnedNation = GetHighWinnerNationRatioByPlayer(item.Key, CurrrentSeason);

                int totalCount = context.Scores.Count(o => o.Player.Name == item.Key && o.Session.Season == CurrrentSeason);

                float itemCount = float.Parse(context.Scores.Count(o => o.Player.Name == item.Key && o.IsWinner && o.Session.Season == CurrrentSeason).ToString());
                float listCount = float.Parse(totalCount.ToString());
                float ratio = float.Parse((itemCount / listCount).ToString("N4"));
                int careerist = GetScoresForCareerist(item.Key, out loseGameCount);

                int excludeCareeristWin = context.Scores.Count(o => o.Player.Name == item.Key && o.IsCareerist && o.IsWinner && o.Session.Season == CurrrentSeason);

                //calculate total score
                int x = int.Parse(((itemCount - excludeCareeristWin) * 3 + careerist + loseGameCount).ToString());
                int y = 0;
                if (kill != 0)
                {
                    y = kill / 3;
                }
                int winTimes = context.Scores.Count(o => o.Player.Name == item.Key && o.IsWinner && o.Session.Season == CurrrentSeason);
                result.Add(new WinRatio { Name = item.Key, TotalTimes = totalCount, Ratio = ratio.ToString("P"), Points = x + y, Kills = kill, WinTimes = winTimes, LoseTimes = totalCount - winTimes, WinnerNation = highWinnedNation });
            }

            var finalResult = result.OrderByDescending(o => o.TotalTimes >= 25).ThenByDescending(o => o.Ratio).ThenByDescending(o => o.Points).ThenByDescending(o => o.Kills).ToList();

            int remainedGames = 50 - finalResult.Max(o => o.TotalTimes);

            for (int i = 0; i < finalResult.Count; i++)
            {
                var name = finalResult[i].Name;
                var param1 = new SqlParameter
                {
                    ParameterName = "playerName",
                    Value = name
                };

                var param2 = new SqlParameter
                {
                    ParameterName = "isChief",
                    Value = 1
                };

                var param3 = new SqlParameter
                {
                    ParameterName = "playerName",
                    Value = name
                };

                var param4 = new SqlParameter
                {
                    ParameterName = "isChief",
                    Value = 0
                };

                var param5 = new SqlParameter
                {
                    ParameterName = "playerName",
                    Value = name
                };

                var param6 = new SqlParameter
                {
                    ParameterName = "isChief",
                    Value = 1
                };

                var param7 = new SqlParameter
                {
                    ParameterName = "playerName",
                    Value = name
                };

                var param8 = new SqlParameter
                {
                    ParameterName = "isChief",
                    Value = 0
                };



                var presentorChief = context.Database.SqlQuery<Presentor>("GetRepresentor @playerName, @isChief", param1, param2).SingleOrDefault();

                var presentorVice = context.Database.SqlQuery<Presentor>("GetRepresentor @playerName, @isChief", param3, param4).SingleOrDefault();

                var favorChief = context.Database.SqlQuery<Presentor>("GetFavorFighter @playerName, @isChief", param5, param6).SingleOrDefault();

                var favorVice = context.Database.SqlQuery<Presentor>("GetFavorFighter @playerName, @isChief", param7, param8).SingleOrDefault();

                finalResult[i].RepresentChief = presentorChief.Name;
                finalResult[i].RepresentVice = presentorVice.Name;
                finalResult[i].FavorChief = favorChief.Name;
                finalResult[i].FavorVice = favorVice.Name;
                finalResult[i].RemainedGames = remainedGames;
            }
            return finalResult.OrderByDescending(o => o.Ratio);
        }



        private int GetHighWinnerNationRatioByPlayer(string name, int season = 0)
        {
            int currentSeason = int.Parse(ConfigurationManager.AppSettings["season"]);
            context = new SGSContext();
            var dic = new Dictionary<int, int>();
            if (season == 0)
            {
                dic.Add(0, context.Scores.Where(o => o.IsWinner && o.Player.Name == name && o.Chief.Nation == Model.Nations.魏).Count());
                dic.Add(1, context.Scores.Where(o => o.IsWinner && o.Player.Name == name && o.Chief.Nation == Model.Nations.蜀).Count());
                dic.Add(2, context.Scores.Where(o => o.IsWinner && o.Player.Name == name && o.Chief.Nation == Model.Nations.吴).Count());
                dic.Add(3, context.Scores.Where(o => o.IsWinner && o.Player.Name == name && o.Chief.Nation == Model.Nations.群).Count());
            }
            else
            {
                dic.Add(0, context.Scores.Where(o => o.IsWinner && o.Player.Name == name && o.Chief.Nation == Model.Nations.魏 && o.Session.Season == currentSeason).Count());
                dic.Add(1, context.Scores.Where(o => o.IsWinner && o.Player.Name == name && o.Chief.Nation == Model.Nations.蜀 && o.Session.Season == currentSeason).Count());
                dic.Add(2, context.Scores.Where(o => o.IsWinner && o.Player.Name == name && o.Chief.Nation == Model.Nations.吴 && o.Session.Season == currentSeason).Count());
                dic.Add(3, context.Scores.Where(o => o.IsWinner && o.Player.Name == name && o.Chief.Nation == Model.Nations.群 && o.Session.Season == currentSeason).Count());
            }
            var nation = dic.Values.Max();
            return dic.FirstOrDefault(o => o.Value == nation).Key;
        }

        private int GetHighUsedNationRatioByPlayer(string name)
        {
            context = new SGSContext();
            var dic = new Dictionary<int, int>();
            dic.Add(0, context.Scores.Where(o => o.Player.Name == name && o.Chief.Nation == Model.Nations.魏).Count());
            dic.Add(1, context.Scores.Where(o => o.Player.Name == name && o.Chief.Nation == Model.Nations.蜀).Count());
            dic.Add(2, context.Scores.Where(o => o.Player.Name == name && o.Chief.Nation == Model.Nations.吴).Count());
            dic.Add(3, context.Scores.Where(o => o.Player.Name == name && o.Chief.Nation == Model.Nations.群).Count());
            var nation = dic.Values.Max();
            return dic.FirstOrDefault(o => o.Value == nation).Key;
        }

        private int GetWinningTimesByFighter(string name)
        {
            context = new SGSContext();

            var count = context.Scores.Where(o => o.IsWinner && (o.Chief.Name == name || o.Vice.Name == name)).Count();
            return count;
        }

        private DTO.Model.Nations GetNationByFighter(string name)
        {
            context = new SGSContext();

            var fighter = context.Fighters.SingleOrDefault(o => o.Name == name);

            FighterDto dto = Mapper.Map<Fighter, FighterDto>(fighter);
            return dto.Nation;
        }

        [Route("api/top10/{page}")]
        public IEnumerable<TopPlayers> GetTop10Players(int page)
        {
            context = new SGSContext();
            List<TopPlayers> list = context.Scores.GroupBy(o => o.Chief.Name).Select(group => new TopPlayers { Name = group.Key, Times = group.Count() }).OrderByDescending(o => o.Times).ToList();

            List<TopPlayers> list2 = context.Scores.GroupBy(o => o.Vice.Name).Select(group => new TopPlayers { Name = group.Key, Times = group.Count() }).OrderByDescending(o => o.Times).ToList();

            List<TopPlayers> temp = new List<TopPlayers>();
            temp = list;
            List<TopPlayers> temp2 = new List<TopPlayers>();
            temp2 = list2;

            for (int i = 0; i < temp.Count; i++)
            {
                for (int j = 0; j < temp2.Count; j++)
                {
                    if (temp2[j].Name == temp[i].Name)
                    {
                        temp[i].Times = temp[i].Times + temp2[j].Times;
                        temp2[j].IsDup = true;
                    }
                }
            }
            temp.AddRange(temp2);

            List<TopPlayers> result = new List<TopPlayers>();

            foreach (var item in temp.Where(o => !o.IsDup).OrderByDescending(o => o.Ratio))
            {
                var nation = GetNationByFighter(item.Name);
                var goalTimes = GetWinningTimesByFighter(item.Name);
                result.Add(new TopPlayers { Name = item.Name, Times = item.Times, Nation = nation, GoalTimes = goalTimes });
            }
            return result.OrderByDescending(o => o.Ratio).ThenByDescending(o => o.Times).Skip(page * 10).Take(10);
        }
        [Route("api/top5/{nation}")]
        public IEnumerable<TopPlayers> GetTop5PlayersByNation(int nation)
        {
            context = new SGSContext();
            List<TopPlayers> list = context.Scores.GroupBy(o => o.Chief.Name).Select(group => new TopPlayers { Name = group.Key, Times = group.Count() }).OrderByDescending(o => o.Times).ToList();

            List<TopPlayers> list2 = context.Scores.GroupBy(o => o.Vice.Name).Select(group => new TopPlayers { Name = group.Key, Times = group.Count() }).OrderByDescending(o => o.Times).ToList();

            List<TopPlayers> temp = new List<TopPlayers>();
            temp = list;
            List<TopPlayers> temp2 = new List<TopPlayers>();
            temp2 = list2;

            for (int i = 0; i < temp.Count; i++)
            {
                for (int j = 0; j < temp2.Count; j++)
                {
                    if (temp2[j].Name == temp[i].Name)
                    {
                        temp[i].Times = temp[i].Times + temp2[j].Times;
                        temp2[j].IsDup = true;
                    }
                }
            }
            temp.AddRange(temp2);
            DTO.Model.Nations belonging = GetNationByCode(nation);
            List<TopPlayers> result = new List<TopPlayers>();

            foreach (var item in temp.Where(o => !o.IsDup).OrderByDescending(o => o.GoalTimes))
            {
                var thenation = GetNationByFighter(item.Name);
                var goalTimes = GetWinningTimesByFighter(item.Name);
                result.Add(new TopPlayers { Name = item.Name, Times = item.Times, Nation = thenation, GoalTimes = goalTimes });
            }

            var finalResult = result.Where(o => o.Nation == belonging).OrderByDescending(o => o.Ratio).Take(5);
            return finalResult;

        }

        [Route("api/top10/chief/{page}")]
        public IEnumerable<TopPlayerSe> GetTop10Chief(int page)
        {
            try
            {
                context = new SGSContext();
                var list = context.Scores.GroupBy(o => o.Chief.Name).Select(group => new { Name = group.Key, Times = group.Count(), WinnerTimes = group.Count(o => o.IsWinner).ToString() }).ToList();

                var list2 = new List<TopPlayerSe>();
                foreach (var item in list)
                {
                    var nation = GetNationByFighter(item.Name);
                    list2.Add(new TopPlayerSe
                    {
                        Name = item.Name,
                        Times = item.Times,
                        WinnerTimes = item.WinnerTimes,
                        //Percentage = (double.Parse(item.WinnerTimes) / double.Parse(item.Times)),
                        Nation = nation
                    });
                }
                //return list2.OrderByDescending(o => o.Percentage).ThenByDescending(o => o.Times).Skip(page * 10).Take(10);

                return list2.OrderByDescending(o => o.Times).ThenByDescending(o => o.Percentage).Skip(page * 10).Take(10);//.ThenByDescending(o => o.Times).Skip(page * 10).Take(10);

                //return list2.OrderByDescending(o => o.Times).ThenByDescending(o => o.Percentage)
                //.Skip(page * 10).Take(10);
            }
            catch (Exception ew)
            {

                throw ew;
            }


        }

        private DTO.Model.Nations GetNationByCode(int code)
        {
            switch (code)
            {
                case 0:
                    return DTO.Model.Nations.魏;
                case 1:
                    return DTO.Model.Nations.蜀;
                case 2:
                    return DTO.Model.Nations.吴;
                default:
                    return DTO.Model.Nations.群;
            }
        }

        [Route("api/top10/vice/{page}")]
        public IEnumerable<TopPlayerSe> GetTop10Vice(int page)
        {
            try
            {
                context = new SGSContext();
                var list = context.Scores.GroupBy(o => o.Vice.Name).Select(group => new { Name = group.Key, Times = group.Count(), WinnerTimes = group.Count(o => o.IsWinner).ToString() }).ToList();

                var list2 = new List<TopPlayerSe>();
                foreach (var item in list)
                {
                    var nation = GetNationByFighter(item.Name);
                    list2.Add(new TopPlayerSe
                    {
                        Name = item.Name,
                        Times = item.Times,
                        WinnerTimes = item.WinnerTimes,
                        //Percentage = (double.Parse(item.WinnerTimes) / double.Parse(item.Times)),
                        Nation = nation
                    });
                }
                return list2.OrderByDescending(o => o.Times).ThenByDescending(o => o.Percentage).Skip(page * 10).Take(10);
            }
            catch (Exception ew)
            {

                throw ew;
            }


        }

        [Route("api/nationratio")]
        public IEnumerable<NationWinRatio> GetNationWinRatio()
        {
            context = new SGSContext();
            var lwei = context.Scores.Where(o => o.IsWinner & o.Chief.Nation == Model.Nations.魏).Select(o => o.Session).Distinct().Count();
            var lshu = context.Scores.Where(o => o.IsWinner & o.Chief.Nation == Model.Nations.蜀).Select(o => o.Session).Distinct().Count();

            var lwu = context.Scores.Where(o => o.IsWinner & o.Chief.Nation == Model.Nations.吴).Select(o => o.Session).Distinct().Count();

            var lqun = context.Scores.Where(o => o.IsWinner & o.Chief.Nation == Model.Nations.群).Select(o => o.Session).Distinct().Count();

            List<NationWinRatio> result = new List<NationWinRatio>();
            int weiTotal = context.Scores.Where(o => o.Chief.Nation == Model.Nations.魏).Select(o => o.Session).Distinct().Count();
            int shuTotal = context.Scores.Where(o => o.Chief.Nation == Model.Nations.蜀).Select(o => o.Session).Distinct().Count();
            int wuTotal = context.Scores.Where(o => o.Chief.Nation == Model.Nations.吴).Select(o => o.Session).Distinct().Count();
            int qunTotal = context.Scores.Where(o => o.Chief.Nation == Model.Nations.群).Select(o => o.Session).Distinct().Count();

            int totalCount = context.Sessions.Count();
            var ratio = (float.Parse(lwei.ToString()) / float.Parse(weiTotal.ToString()));
            result.Add(new NationWinRatio { Name = Model.Nations.魏.ToString(), WinRatio = ratio.ToString("P") });
            ratio = (float.Parse(lshu.ToString()) / float.Parse(shuTotal.ToString()));
            result.Add(new NationWinRatio { Name = Model.Nations.蜀.ToString(), WinRatio = ratio.ToString("P") });

            ratio = (float.Parse(lwu.ToString()) / float.Parse(wuTotal.ToString()));
            result.Add(new NationWinRatio { Name = Model.Nations.吴.ToString(), WinRatio = ratio.ToString("P") });

            ratio = (float.Parse(lqun.ToString()) / float.Parse(qunTotal.ToString()));
            result.Add(new NationWinRatio { Name = Model.Nations.群.ToString(), WinRatio = ratio.ToString("P") });

            return result.OrderByDescending(o => o.WinRatio);
        }

        [Route("api/nationratio/history")]
        public IEnumerable<HistoryNationRatioMap> GetNationHistoryRecords()
        {
            using (context = new SGSContext())
            {
                List<HistoryNationRatioMap> result = new List<HistoryNationRatioMap>();

                int[] nations = { 0, 1, 2, 3 };
                List<Session> sessions = context.Sessions.ToList();

                var days = GetAllGameDate(context);

                var history = new HistoryNationRatioMap();
                history.TheDay = days;



                for (int i = 0; i < 4; i++)
                {
                    List<float> ratios = new List<float>();
                    var nationName = "";
                    foreach (var day in days)
                    {

                        var winRatio = CalculateNationRatioPerDay(DateTime.Parse(day), context, i);

                        switch (i)
                        {
                            case 0:
                                nationName = "魏";
                                break;
                            case 1:
                                nationName = "蜀";
                                break;
                            case 2:
                                nationName = "吴";
                                break;
                            default:
                                nationName = "群";
                                break;
                        }
                        ratios.Add(CalculateNationRatioPerDay(DateTime.Parse(day), context, i));
                    }
                    result.Add(new HistoryNationRatioMap { TheDay = days, NationCode = i, NationName = nationName, WinRatio = ratios });
                }
                return result;
            }

        }

        private float CalculateNationRatioPerDay(DateTime dt, SGSContext context, int NationCode)
        {
            DateTime mydt = dt.AddHours(23).AddMinutes(59).AddSeconds(59);
            int wins = context.Scores.Where(o => o.IsWinner & o.Chief.Nation == (Model.Nations)NationCode && o.Session.GameDate <= mydt).Select(o => o.Session).Distinct().Count();


            int total = context.Scores.Where(o => o.Chief.Nation == (Model.Nations)NationCode && o.Session.GameDate <= mydt).Select(o => o.Session).Distinct().Count();

            return float.Parse(wins.ToString()) / float.Parse(total.ToString());
        }

        private int GetTotalGames(SGSContext context, DateTime dt)
        {
            return context.Sessions.Count(o => o.GameDate.Date == dt);

        }

        private List<string> GetAllGameDate(SGSContext context)
        {
            var list = new List<string>();

            var sessions = context.Sessions.ToList();

            foreach (var session in sessions)
            {
                if (!list.Contains(session.GameDate.Date.ToShortDateString()))
                {
                    list.Add(session.GameDate.Date.ToShortDateString());
                }
            }

            return list;
        }


        [Route("api/season/detail/{season}")]
        public IEnumerable<SeasonDetail> GetSeasonDetail(int season)
        {
            using (context = new SGSContext())
            {
                List<SeasonDetail> list = new List<SeasonDetail>();

                List<Player> players = context.Players.ToList();

                foreach (var player in players)
                {
                    //for all games in the past season
                    if (season == 0)
                    {
                        if (context.Scores.Count(o => o.Player.Name == player.Name) > 25)
                        {
                            var detail = new SeasonDetail();
                            detail.SeasonID = 0;
                            detail.PlayerName = player.Name;
                            List<string> days = new List<string>();
                            detail.DaliyRatio = GetPercentByPlayerInSeason(season, player.Name, out days);
                            detail.Days = days;
                            list.Add(detail);
                        }
                    }
                    else
                    {
                        if (context.Scores.Count(o => o.Player.Name == player.Name && o.Session.Season == season) > 0)
                        {
                            var detail = new SeasonDetail();
                            detail.SeasonID = season;
                            detail.PlayerName = player.Name;
                            List<string> days = new List<string>();
                            detail.DaliyRatio = GetPercentByPlayerInSeason(season, player.Name, out days);
                            detail.Days = days;
                            list.Add(detail);
                        }
                    }
                }
                return list;
            }
        }

        private List<float> GetPercentByPlayerInSeason(int season, string name, out List<string> totalDays)
        {
            try
            {
                List<float> daliyRatio = new List<float>();
                List<DateTime> days = new List<DateTime>();
                var context = new SGSContext();
                if (season == 0)
                {
                    foreach (var day in context.Sessions)
                    {
                        days.Add(day.GameDate.Date);
                    }
                }
                else
                {
                    foreach (var day in context.Sessions.Where(o => o.Season == season))
                    {
                        days.Add(day.GameDate.Date);
                    }
                }
                totalDays = new List<string>();

                foreach (var day in days.Distinct())
                {
                    totalDays.Add(day.Date.ToShortDateString());
                }

                if (season != 0)
                {

                    foreach (var day in days.Distinct())
                    {
                        DateTime myday = day.AddHours(23).AddMinutes(59).AddSeconds(59);


                        string win = context.Scores.Where(o => o.Player.Name == name && o.Session.GameDate <= myday && o.IsWinner && o.Session.Season == season).Count().ToString();

                        string total = context.Scores.Where(o => o.Player.Name == name && o.Session.GameDate <= myday && o.Session.Season == season).Count().ToString();

                        float ratio = 0.00f;
                        if (total != "0")
                        {
                            ratio = float.Parse(win) / float.Parse(total);
                        }

                        daliyRatio.Add(ratio);
                    }
                }
                else
                {
                    foreach (var day in days.Distinct())
                    {
                        string win = context.Scores.Where(o => o.Player.Name == name
                        && o.Session.GameDate.Year <= day.Year
                        && ((o.Session.GameDate.Month <= day.Month && o.Session.GameDate.Day <= day.Day)
                        || (o.Session.GameDate.Month < day.Month && o.Session.GameDate.Day > day.Day))
                        && o.IsWinner).Count().ToString();

                        string total = context.Scores.Where(o => o.Player.Name == name
                        && o.Session.GameDate.Year <= day.Year
                        && ((o.Session.GameDate.Month <= day.Month && o.Session.GameDate.Day <= day.Day)
                        || (o.Session.GameDate.Month < day.Month && o.Session.GameDate.Day > day.Day))).Count().ToString();

                        float ratio = 0.00f;
                        if (total != "0")
                        {
                            ratio = float.Parse(win) / float.Parse(total);
                        }

                        daliyRatio.Add(ratio);
                    }
                }

                return daliyRatio;
            }
            catch (Exception ex)
            {

                throw ex;
            }
        }

        private List<MyDataset> GetMyDatasets(List<string> names, int season)
        {
            try
            {
                context = new SGSContext();
                List<MyDataset> mds = new List<MyDataset>();
                List<string> mydata = new List<string>();



                int win = 0;
                int total = 1;


                if (season != 0)
                {
                    season = CurrrentSeason;
                    foreach (var name in names)
                    {
                        MyDataset md = new MyDataset();
                        md.data = new List<float>();
                        for (int i = 0; i < 4; i++)
                        {
                            switch (i)
                            {
                                case 0:
                                    md.label = "魏";
                                    md.backgroundColor = "rgba(81,145,255,0.8)";
                                    break;
                                case 1:
                                    md.label = "蜀";
                                    md.backgroundColor = "rgba(224,139,85,0.8)";
                                    break;
                                case 2:
                                    md.label = "吴";
                                    md.backgroundColor = "rgba(126,171,68,0.8)";
                                    break;
                                default:
                                    md.label = "群";
                                    md.backgroundColor = "rgba(118,111,153,0.8)";
                                    break;
                            }
                            win = context.Scores.Where(o => o.Player.Name == name && o.IsWinner && o.Session.Season == season && o.Chief.Nation == (Model.Nations)i).Count();
                            total = context.Scores.Where(o => o.Player.Name == name && o.Session.Season == season && o.Chief.Nation == (Model.Nations)i).Count();
                            md.data.Add(float.Parse(win.ToString("N4")) / float.Parse(total.ToString("N4")));
                        }
                        mds.Add(md);
                    }
                }
                else
                {

                    for (int i = 0; i < 4; i++)
                    {
                        MyDataset md = new MyDataset();
                        md.data = new List<float>();

                        foreach (var name in names)
                        {
                            switch (i)
                            {
                                case 0:
                                    md.label = "魏";
                                    md.backgroundColor = "rgba(81,145,255,0.8)";
                                    break;
                                case 1:
                                    md.label = "蜀";
                                    md.backgroundColor = "rgba(224,139,85,0.8)";
                                    break;
                                case 2:
                                    md.label = "吴";
                                    md.backgroundColor = "rgba(126,171,68,0.8)";
                                    break;
                                default:
                                    md.label = "群";
                                    md.backgroundColor = "rgba(118,111,153,0.8)";
                                    break;
                            }
                            win = context.Scores.Where(o => o.Player.Name == name && o.IsWinner && o.Chief.Nation == (Model.Nations)i).Count();
                            total = context.Scores.Where(o => o.Player.Name == name && o.Chief.Nation == (Model.Nations)i).Count();
                            md.data.Add(float.Parse(win.ToString("N2")) / float.Parse(total.ToString("N2")));
                        }
                        mds.Add(md);
                    }
                }
                return mds;
            }
            catch (Exception ex)
            {

                throw;
            }
        }
        [Route("api/nationwin/{season}")]
        public RatioByNationByName GetRatioByNationByName(int season)
        {
            List<RatioByNationByName> list = new List<RatioByNationByName>();
            context = new SGSContext();

            List<string> names = new List<string>();
            //foreach (var player in context.Players)
            //{
            //    names.Add(player.Name);
            //}

            RatioByNationByName result = new RatioByNationByName();
            result.labels = GetValidatedPlayers();
            List<MyDataset> mydatasets = new List<MyDataset>();

            result.datasets = GetMyDatasets(result.labels, season);
            //foreach (var name in names)
            //{
            //    if (context.Scores.Count(o => o.Player.Name == name) > 24)
            //    {
            //        var item = GetRatioByName(name, season);
            //        //var result = new RatioByNationByName { Name = name.Name, RatioDic = item };
            //        //list.Add(result);

            //    }
            //}

            return result;



        }

        private List<string> GetValidatedPlayers()
        {
            context = new SGSContext();
            List<string> names = new List<string>();
            List<string> results = new List<string>();
            foreach (var player in context.Players)
            {
                names.Add(player.Name);
            }

            foreach (var name in names)
            {
                if (context.Scores.Count(o => o.Player.Name == name) > 24)
                {
                    results.Add(name);
                }
            }

            return results;
        }

        // POST api/values
        [Route("api/scores")]
        public void Post([FromBody] List<GameRecord> objects)
        {
            try
            {
                var season = ConfigurationManager.AppSettings["season"];
                Session session = new Session { GameDate = DateTime.Now, PlayerNumber = objects.Count, Season = int.Parse(season) };

                context = new SGSContext();
                int count = context.Fighters.Count();

                foreach (var obj in objects)
                {
                    string f1 = obj.Chief;
                    string f2 = obj.Vice;
                    var fighter = context.Fighters.SingleOrDefault(o => o.Name == f1);
                    var fighter1 = context.Fighters.SingleOrDefault(o => o.Name == f2);
                    var player = context.Players.Single(o => o.Name == obj.Name);
                    var score = new Score { Player = player, IsWinner = obj.Win, IsShowFirst = obj.Show, Session = session, Chief = fighter, Vice = fighter1, IsCareerist = obj.Careerist, Kills = obj.Kills };
                    context.Scores.Add(score);
                }
                context.SaveChanges();
            }
            catch (Exception w)
            {
                throw w;
            }
        }

        [Route("api/testing")]
        public void Post([FromBody] Dictionary<string, object> objects)
        {
            foreach (var item in objects)
            {
                JsonWebToken.Decode(item.Value.ToString(), item.Key, true);
            }
            //JsonWebToken.Decode()
        }

        // PUT api/values/5
        public void Put(int id, [FromBody]string value)
        {
        }

        // DELETE api/values/5
        public void Delete(int id)
        {
        }
    }

    public class Presentor
    {
        public int GoalCount { get; set; }
        public string Name { get; set; }
    }
}
